package alkaid.eis.schedule.controller;

import static org.springframework.util.StringUtils.hasText;

import java.util.Set;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import alkaid.eis.schedule.domain.JobInfo;
import alkaid.eis.schedule.domain.JobInfoRepository;
import alkaid.eis.schedule.domain.JobInfoSpecifications;
import alkaid.eis.schedule.domain.JobLog;
import alkaid.eis.schedule.domain.JobLogRepository;
import alkaid.eis.schedule.domain.JobLogSpecifications;
import alkaid.eis.schedule.domain.JobService;
import alkaid.eis.schedule.domain.JobLog.Level;
import lombok.RequiredArgsConstructor;

/**
 * 任务接口
 * 
 * @author Lucky Yang
 * @since 0.0.1
 */
@RestController
@RequestMapping("/jobs")
@RequiredArgsConstructor
public class JobController {
    private final JobInfoRepository jobInfoRepository;
    private final JobLogRepository jobLogRepository;
    private final JobService jobService;

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Long create(@RequestBody JobInfoDto dto) {
        JobInfo entity = jobService.saveInfo(JobInfoMapper.INST.toEntity(dto));
        return entity.getId();
    }

    @PutMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void update(@PathVariable("id") Long id, @RequestBody JobInfoDto dto) {
        dto.setId(id);
        jobService.saveInfo(JobInfoMapper.INST.toEntity(dto));
    }
    
    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void delete(@PathVariable("id") Long id) {
        jobInfoRepository.deleteById(id);
    }

    @GetMapping("/info")
    public Page<JobInfoDto> getInfoPage(@RequestParam(value = "beanName", required = false) String beanName,
            @RequestParam(value = "remark", required = false) String remark, Pageable pageable) {
        Specification<JobInfo> where = JobInfoSpecifications.empty();
        if (hasText(beanName)) {
            where = where.and(JobInfoSpecifications.beanNameLike(beanName));
        }
        if (hasText(remark)) {
            where = where.and(JobInfoSpecifications.remarkLike(remark));
        }

        Page<JobInfo> page = jobInfoRepository.findAll(where, pageable);
        return page.map(JobInfoMapper.INST::toDto);
    }

    @GetMapping("/log")
    public Page<JobLogDto> getLogPage(@RequestParam(value = "jobInfoId", required = false) Long jobInfoId,
            @RequestParam(value = "level", required = false) Set<Level> levels, Pageable pageable) {
        Specification<JobLog> where = JobLogSpecifications.empty();
        if (jobInfoId != null) {
            JobInfo jobInfo = jobService.findInfoById(jobInfoId);
            where = where.and(JobLogSpecifications.jobInfoEqual(jobInfo));
        }
        if (levels != null) {
            where = where.and(JobLogSpecifications.levelIn(levels));
        }

        Page<JobLog> page = jobLogRepository.findAll(where, pageable);
        return page.map(JobLogMapper.INST::toDto);
    }    
}
